using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using log4net;
using Triton.Common;
using Triton.Common.LogUtilities;

namespace Triton.Bot.Profiles
{
	public class ProfileLoader
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class Class220
		{
			public static readonly Class220 Instance9 = new Class220();

			internal void method_0(object sender, NotifyCollectionChangedEventArgs e)
			{
				smethod_0();
			}
		}

		private static readonly TypeFinder<ProfileElement> typeFinder_0;

		private static readonly Dictionary<string, Type> dictionary_0;

		private static readonly ILog ilog_0;

		static ProfileLoader()
		{
			typeFinder_0 = new TypeFinder<ProfileElement>(includeGacAssemblies: false, createInstances: false);
			dictionary_0 = new Dictionary<string, Type>();
			ilog_0 = Logger.GetLoggerInstanceForType();
			typeFinder_0.CollectionChanged += delegate
			{
				smethod_0();
			};
			smethod_0();
		}

		private static void smethod_0()
		{
			dictionary_0.Clear();
			foreach (Type instanceType in typeFinder_0.InstanceTypes)
			{
				ProfileElementNameAttribute customAttribute = instanceType.GetCustomAttribute<ProfileElementNameAttribute>();
				if (customAttribute != null)
				{
					dictionary_0.Add(customAttribute.ElementName, instanceType);
				}
			}
		}

		public static ProfileElement LoadElement(List<ProfileElement> currentList, XElement element)
		{
			try
			{
				string localName = element.Name.LocalName;
				if (dictionary_0.TryGetValue(localName, out var value))
				{
					using (XmlReader xmlReader = element.CreateReader())
					{
						ProfileElement obj = new XmlSerializer(value).Deserialize(xmlReader) as ProfileElement;
						obj.LoadElement(currentList, element);
						return obj;
					}
				}
			}
			catch (InvalidOperationException ex)
			{
				ilog_0.Error("An error occurred while loading the profile. Are you sure the profile contains no XML errors?");
				ilog_0.ErrorFormat("XML Error: {0}", (ex.InnerException != null) ? ex.InnerException.ToString() : "None");
			}
			return null;
		}

		public static Profile LoadProfile(string path)
		{
			XmlSerializer serializerForCurrentDomain = XmlSerializerFactory.GetSerializerForCurrentDomain<Profile, ProfileElement>();
			XElement xElement = XElement.Load(File.OpenRead(path));
			Profile profile = serializerForCurrentDomain.Deserialize(File.OpenRead(path)) as Profile;
			if (xElement != null && profile != null)
			{
				foreach (XElement item in xElement.Elements())
				{
					ProfileElement profileElement = LoadElement(profile.Elements, item);
					if (profileElement != null)
					{
						profile.Elements.Add(profileElement);
					}
					else
					{
						ilog_0.Error(string.Concat("Unknown profile element: ", item, " at line ", ((IXmlLineInfo)item).LineNumber));
					}
				}
				return profile;
			}
			throw new Exception("Error while loading profile! Loaded Element was null.");
		}
	}
}
